using System;
using System.Collections.Generic;
using Gj.Galaxy.Logic;
using Gj.Services;
using UnityEngine;

namespace Gj
{
    public enum InfoKey : byte
    {
        TargetKey,
        ServerKey,
        MapKey,
        Wait,
        Confirm,
        MakeKey,
        RelationKey,
        ObjectDataKey,
        ActorDataKey,
        TaskKey,
        TaskProcessKey,
        IdentityKey,
        UiKey,
        DataKey,
        OpenMapKey,
        MasterKey
    }

    public enum DetailKey : byte
    {
        Key,
        Value
    }

    public enum MakeKey : byte
    {
        Id,
        Category,
        Relation,
        X,
        Y,
        Z
    }

    public class CorePlugin : GamePlugin
    {
        private readonly Queue<object[]> makeQueue = new();

        public void OnInit(BaseGameSpace space)
        {
            SyncService.SetEntityManager(ObjectService.EntityManager);
        }

        public void OnDestroy()
        {
        }

        public GameService[] GetRequireService()
        {
            return new GameService[]
            {
                CacheService.single, ObjectService.single, RelationService.single, EngineService.single,
                ControlService.single, AttrService.single, TerrainService.single, StatisticsService.single
            };
        }

        public void OnUpdate()
        {
        }

        public void LateUpdate()
        {
            if (makeQueue.Count > 0)
            {
                var item = makeQueue.Dequeue();
                // todo 判断坐标，如果为空，则本地随机
//                Debug.LogFormat("position:{0},{1},{2}", (float) item[(byte) MakeKey.X], (float) item[(byte) MakeKey.Y],
//                    (float) item[(byte) MakeKey.Z]);

                var objectCategory = (ControlType)Convert.ToInt32(item[(byte)MakeKey.Category]);
                var key = ControlService.single.MakeKey(objectCategory, Convert.ToInt32(item[(byte)MakeKey.Id]));
                Debug.LogFormat("make:{0}, {1}", objectCategory, Convert.ToInt32(item[(byte)MakeKey.Id]));
                var relation = (byte)item[(byte)MakeKey.Relation];
                try
                {
                    SyncService.Instance(key, relation,
                        relation == 1 || relation == 4
                            ? TerrainService.single.GetBirthPoint(Convert.ToInt32(item[(byte)MakeKey.Id]))
                            : TerrainService.single.GetBirthPoint());
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                }
            }
        }

        public void OnProcessRoom(object[] data)
        {
            // 处理进程
            foreach (object[] detail in data)
            {
                var key = (InfoKey)detail[(byte)DetailKey.Key];
                switch (key)
                {
                    case InfoKey.TargetKey:
                        ControlService.single.SetTarget((object[])detail[(byte)DetailKey.Value]);
                        break;
                    case InfoKey.MakeKey:
                        var item = (object[])detail[(byte)DetailKey.Value];
                        // 添加进创建对象池
                        makeQueue.Enqueue(item);
                        break;
                }
            }
        }

        public void OnFinish(object result)
        {
            // 游戏结束，可以执行离开游戏
            ControlService.single.OnFinish();
        }

        public void OnSwitchArea()
        {
        }

        public void OnInstance(int targetIndex, byte relation, GamePlayer player, Vector3 position, bool isLocal,
            NetworkEsse master, Action<InitSyncListener> cb)
        {
        }

        public void OnDestroy(NetworkEsse instance, GamePlayer player)
        {
        }

        public void OnBroadcast(GamePlayer player, byte code, Vector3 position, StreamReader reader)
        {
        }

        public void OnEnterRoom(bool first)
        {
        }

        public void OnPlayerJoin(GamePlayer player)
        {
        }

        public void OnPlayerLeave(GamePlayer player)
        {
        }

        public void OnPlayerRejoin(GamePlayer player)
        {
        }

        public void OnFailConnect()
        {
        }

        public void OnReady()
        {
        }

        public void OnReadyPlayer(GamePlayer player)
        {
        }

        public void OnInitGame()
        {
        }

        public void OnStart()
        {
        }

        public void OnReadyAll()
        {
        }

        public void OnTimeMove(int startTime, int endTime, StreamReader reader, Vector3[] positions, int index,
            Vector3 middlePosition)
        {
        }

        public void OnTimeProcess(int startTime, int endTime, StreamReader reader)
        {
        }
    }
}